// $codepro.audit.disable com.instantiations.assist.eclipse.analysis.audit.rule.effectivejava.alwaysOverridetoString.alwaysOverrideToString
/*
 * NetworkMain.java
 */
package edu.gatech.oad.networking;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

import javax.jmdns.JmDNS;
import javax.jmdns.ServiceInfo;
import javax.swing.JFrame;

import org.jhotdraw.app.osx.OSXAdapter;

import edu.gatech.oad.persistence.PersistenceManager;
import edu.gatech.oad.records.TreatmentRecord;
import edu.gatech.oad.schedule.Appointment;
import edu.gatech.oad.schedule.AppointmentController;
import edu.gatech.oad.user.AccountsController;
import edu.gatech.oad.user.Doctor;
import edu.gatech.oad.user.MedicalPersonnelAvailability;
import edu.gatech.oad.user.MedicalPersonnelSchedule;
import edu.gatech.oad.user.Nurse;
import edu.gatech.oad.user.Patient;
import edu.gatech.oad.user.Receptionist;
import edu.gatech.oad.user.SystemAdministrator;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.ArrayList;

public class NetworkMain {

	private static JmDNS mDNS; // $codepro.audit.disable staticFieldNamingConvention
	
	private static final int MAX_DAYS = 31;
	
	private static final String FILENAME = "Mufasa.dat";
	
	public static String pathForFile() {
		final String userHome = System.getProperty("user.home");
		final File userDir = new File(userHome, NetworkMain.FILENAME);
		return userDir.toString();
	}
	
	public static void addUsers(){
		//adds some people (testing purposes)
		final Patient patient =
			AccountsController.sharedController().addPatientForUsername("A");
		patient.setPassword("B");
		patient.setFirstName("Joey");
		patient.setLastName("Slater");
		patient.setEmailAddress("joeyslater@gatech.edu");
		final List<String> reasons = new ArrayList<String>();
		reasons.add("Ouch");
		reasons.add("No");
		
		final Doctor doctor = AccountsController.sharedController().addDoctorForUsername(
				"Doc");
		doctor.setPassword("doc");
		doctor.setFirstName("James");
		doctor.setLastName("Wilson");
		final Doctor doctor1 = AccountsController.sharedController().addDoctorForUsername(
				"House");
		doctor1.setPassword("Cuddy");
		doctor1.setFirstName("Greg");
		doctor1.setLastName("House");
		final Doctor doctor2 = AccountsController.sharedController().addDoctorForUsername(
				"Holmes");
		doctor2.setPassword("Sherlock");
		doctor2.setFirstName("Sherlock");
		doctor2.setLastName("Home");
		final List<MedicalPersonnelAvailability> data =
			new ArrayList<MedicalPersonnelAvailability>();
		for(int i = 1; i < NetworkMain.MAX_DAYS; i++){
			MedicalPersonnelAvailability workday =
				new MedicalPersonnelAvailability(Calendar.getInstance().getTime(),
						doctor1);
			workday.setDay(i);
			data.add(i - 1, workday);
		}
		final MedicalPersonnelSchedule mps = new MedicalPersonnelSchedule(data);
		doctor1.setSchedule(mps);
		
		final Nurse nurse = AccountsController.sharedController().addNurseForUsername("nurse");
		nurse.setPassword("nurse");
		
		final SystemAdministrator admin =
			AccountsController.sharedController().addSystemAdministratorForUsername(
					"admin");
		admin.setPassword("mufasa.admin");
		
		final Receptionist receptionist = AccountsController.sharedController().
			addReceptionistForUsername("receptionist");
		receptionist.setPassword("receptionist");
		
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			try {
				AccountsController controller = (AccountsController) PersistenceManager.load(pathForFile());
				if (controller != null) {
					AccountsController.setSharedController(controller);
				}
				else {
					addUsers();
					PersistenceManager.save(AccountsController.sharedController(), pathForFile());
				}
			}
			catch (FileNotFoundException e) {
				addUsers();
				PersistenceManager.save(AccountsController.sharedController(), pathForFile());
			}
			
			mDNS = JmDNS.create();
			
			final ServiceInfo info = ServiceInfo.create("_mufasaserver._tcp.local.",
					"Mufasa Server",
					Registry.REGISTRY_PORT,
					"RMI registry for Mufasa");
			mDNS.registerService(info);
			
			if (System.getSecurityManager() == null) {
				System.setSecurityManager(new SecurityManager());
			}
			
			Registry registry = null;
			registry = LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
			
			final IServiceProvider serviceProvider = new ServiceProvider();
			
			serviceProvider.setCurrentAccounts(AccountsController.sharedController());
			
			final IServiceProvider stub =
				(IServiceProvider) UnicastRemoteObject.exportObject(
					serviceProvider,
					0);
			
			registry.rebind("IServiceProvider", stub);
			
			final JFrame frame = new JFrame(); //The main frame
			frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
			frame.setLayout(new BorderLayout());
	        frame.setTitle("M.U.F.A.S.A. Server");
	        
	        frame.setVisible(true);
			
	        frame.addWindowListener(new WindowAdapter() {
	        	public void windowClosing(WindowEvent e) {
	                NetworkMain.windowClosing();
	            }
			});
	        
	        OSXAdapter.setQuitHandler(new ActionListener() {

				@Override
				public void actionPerformed(ActionEvent arg0) {
					// TODO Auto-generated method stub
					System.out.println("About to quit server...");
					NetworkMain.windowClosing();
					System.exit(0);
				}
				
			});
	        
			//ServiceInfo service = ServiceInfo.create("_http._tcp.local.", "M.U.F.A.S.A. Server", Registry.REGISTRY_PORT, "The server for Mufasa");
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static void windowClosing() {
		System.out.println("We're going down...");
		mDNS.unregisterAllServices();
		try {
			mDNS.close(); // $codepro.audit.disable closeInFinally
			mDNS = null;
		}
		catch (IOException e) {
			e.printStackTrace();
		}
	}
	
}
